﻿using System;
using System.Collections.Generic;

using OpenTK;
using OpenTK.Graphics.OpenGL;

namespace Demo
{
    public class RenderPass
    {
        private int framebuffer = 0;
        private int renderbuffer = 0;
        private int texture = 0;
        public RenderPass()
        {
        }

        private RenderPass(int fbo,int rbo,int tex)
        {
            framebuffer = fbo;
            renderbuffer = rbo;
            texture = tex;
        }

        public Action RenderFunc { get; set; }
        public int RenderTexture
        {
            get
            {
                return texture;
            }
        }

        public void Render()
        {
            if (framebuffer == 0)
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            else
            {
                GL.BindFramebuffer(FramebufferTarget.Framebuffer, framebuffer);
                if (renderbuffer != 0)
                {
                    GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderbuffer);
                    GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, RenderbufferTarget.Renderbuffer, renderbuffer);
                    FramebufferErrorCode status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
                    if (status != FramebufferErrorCode.FramebufferComplete)
                        throw new Exception(status.ToString());
                }
                if (texture!=0)
                {
                    GL.BindTexture(TextureTarget.Texture2D, texture);
                    GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, texture, 0);
                    FramebufferErrorCode status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
                    if (status != FramebufferErrorCode.FramebufferComplete)
                        throw new Exception(status.ToString());
                }
            }

            if (RenderFunc != null)
                RenderFunc();
        }

        public static RenderPass CreateFrameBufferRenderBuffer(int width, int height)
        {
            int fbo = GL.GenFramebuffer();
            int rbo = GL.GenRenderbuffer();
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, rbo);
            GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Rgba32f, width, height);
            return new RenderPass(fbo, rbo, 0);
        }

        public static RenderPass CreateFrameBufferTexture(int width, int height)
        {
            int fbo = GL.GenFramebuffer();
            int tex = GL.GenTexture();
            GL.Enable(EnableCap.Texture2D);
            GL.BindTexture(TextureTarget.Texture2D, tex);
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba32f, width, height, 0, PixelFormat.Rgba, PixelType.Float, IntPtr.Zero);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            return new RenderPass(fbo, 0, tex);
        }
    }
}
